package tree.huffman;

import java.io.*;
import java.util.Map;

/**
 * @Auther Jun jie Yi
 * @Date 21:22 2021/7/22
 */
public class FileZip {
    public static void main(String[] args) {
        //FileZip.zipFile("C:\\Users\\yijunjie\\Desktop\\aa.zip", "C:\\Users\\yijunjie\\Desktop\\bb.zip");

        FileZip.unZipFile("C:\\Users\\yijunjie\\Desktop\\bb.zip", "C:\\Users\\yijunjie\\Desktop\\res.zip");
    }

    //根据huffman编码压缩文件的方法
    public static void zipFile(String scrFile, String dstFile) {
        //创建输出流
        OutputStream os = null;
        ObjectOutputStream oos = null;
        //创建文件的输入流
        FileInputStream is = null;
        try {
            is = new FileInputStream(scrFile);
            byte[] b = new byte[is.available()];
            is.read(b);
            //对 b 进行压缩操作
            byte[] huffmanBytes = HuffmanCode.huffmanZip(b);
            //获取huffman编码表
            Map<Byte, String> huffmanCodes = HuffmanCode.getCodes(b);
            //创建文件的输出流，存放压缩文件
            os = new FileOutputStream(dstFile);
            //创建一个和文件输出流关联的 ObjectOutputStream (参考序列化文件存储)
            oos = new ObjectOutputStream(os);
            //把huffman编码后的字节数组写入压缩文件
            oos.writeObject(huffmanBytes);
            //把huffman编码表写入
            oos.writeObject(huffmanCodes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
                oos.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    //根据huffman编码解压文件的方法
    public static void unZipFile(String zipFile, String dstFile) {
        //定义文件的输入流
        InputStream is = null;
        //定义一个对象的输入流
        ObjectInputStream ois = null;
        //定义文件的输出流
        OutputStream os = null;
        try {
            //创建文件的输入流
            is = new FileInputStream(zipFile);
            //创建一个和 is 关联的对象输入流
            ois = new ObjectInputStream(is);
            //???这里能够直接强转得到数据吗？这是对象流的方式读取
            //读取 byte 数组 huffmanBytes
            byte[] huffmanBytes = (byte[]) ois.readObject();
            //读取huffman编码表
            Map<Byte, String> huffmanCodes = (Map<Byte, String>) ois.readObject();
            //解码
            byte[] decodeBytes = HuffmanCode.decode(huffmanCodes, huffmanBytes);
            //将解码数组写到目标文件
            os = new FileOutputStream(dstFile);
            os.write(decodeBytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                os.close();
                ois.close();
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}